package pku.tcs.wsc.compositionSystem;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Vector;

import pku.tcs.wsc.parser.OWLParser;
import pku.tcs.wsc.service.Service;

public class CompositionAlgorithm {



	public static ArrayList<Service> startQuery(Service requiredService,Vector<Service> ServiceVector,OWLParser owlParser) {

		// availbeInputs has all the available concepts that can be consumed by
		// WS not only input concepts
		HashSet<String> availbeInputs = new HashSet<String>();
		for (String inputInstance : requiredService.inputInstances)
			availbeInputs.addAll(owlParser.getAncestorConcepts(inputInstance));

		// unsatisfiedOutputs has only output concepts
		HashSet<String> unsatisfiedOutputs = new HashSet<String>();
		for (String outputInstance : requiredService.outputInstances)
			unsatisfiedOutputs.add(owlParser.getConcept(outputInstance));

		ArrayList<Service> selectedServices = new ArrayList<Service>();
		HashSet<String> selectedServicesSet = new HashSet<String>();

		while (true) {
			//System.out.println(selectedServices.size());
			for (Service s : ServiceVector) {

				// pass the selected service
				if (selectedServicesSet.contains(s.id))
					continue;

				// check whether the service can be started
				boolean isSatisfied = true;
				for (String ins : s.inputInstances) {
					if (!availbeInputs.contains(owlParser.getConcept(ins))) {
						isSatisfied = false;
						break;
					}
				}
				if (!isSatisfied)
					continue;

				// add this service into result list
				//System.out.println(s.id+" is added");
				selectedServices.add(s);
				selectedServicesSet.add(s.id);

				// add all the output of s and their ancestors into
				// availbeInputs
				for (String inIns : s.outputInstances)
					availbeInputs.addAll(owlParser.getAncestorConcepts(inIns));

				// remove the satisfied output from unsatisfiedOutputs
				
				ArrayList<String> removeList=new ArrayList<String>();
				//the concept should not be removed directly from HashSet!
				for (String outConcept : unsatisfiedOutputs) {
					if (availbeInputs.contains(outConcept))
						removeList.add(outConcept);
				}
				unsatisfiedOutputs.removeAll(removeList);
				break; // is break efficient?
			}
			if (unsatisfiedOutputs.size() == 0)
				return selectedServices;
		}

	}
}
